﻿using System;
using System.Data;
using System.Windows.Forms;
using SdmxMl.Structure;
using SdmxMl.Manager;
using SdmxMl.Common;

namespace SdmxMl.UC
{
    /// <summary>
    /// User control for View / Edit of concept & scheme references
    /// </summary>
    public partial class UcConceptRef : UserControl
    {
        #region Internal members

        private ISdmxArtefactRef arSchemeRef;
        private ISdmxArtefactRef arConceptRef;
        private ArtefactList alConceptSchemeRefList = null;
        private bool onBinding;
       
        private ConceptSchemeType cst = null;
        private ConceptType c = null;

        #endregion

        #region EventsHandler

        public event EventHandler ConceptSelect;

        public void RaiseConceptSelect()
        {
            EventHandler eventHandler = this.ConceptSelect;
            if (eventHandler != null)
                this.ConceptSelect(this, EventArgs.Empty);
        }
        #endregion //EventsHandler

        #region Properties

        public string ConceptName
        {
            get { return textBoxConceptName.Text; }
        }

        public string ConceptId
        {
            get { return multiColumnConceptRef.Text; }
        }
        public bool IsFinal { get; set; }

        #endregion

        #region Constructor

        public UcConceptRef()
        {
            InitializeComponent();
        }
        #endregion

        #region Binding

        public void BindRef(ISdmxArtefactRef arSchemeRef, ISdmxArtefactRef arConceptRef)
        {
            onBinding = true;
            this.arConceptRef = arConceptRef;
            this.arSchemeRef = arSchemeRef;

            if (arSchemeRef == null || arConceptRef == null)
            {
                textBoxConceptSchemeRefName.Text = string.Empty;
                textBoxAgency.Text = string.Empty;
                multiColumnConceptSchemeRef.Text = null;
                multiColumnConceptSchemeRef.DataSource = null;
                multiColumnConceptRef.DataSource = null;
                multiColumnConceptRef.Text = null;
            }
            else
            {
                alConceptSchemeRefList = InitSchemeRefControls(arSchemeRef, multiColumnConceptSchemeRef, textBoxAgency, textBoxConceptSchemeRefName);
                cst = ReferenceManager.LocateConceptScheme(arSchemeRef);

                BindConcept(cst, arConceptRef.Id);
                multiColumnConceptSchemeRef.Enabled = IsFinal == false;
                multiColumnConceptRef.Enabled = IsFinal == false;
                buttonAddUrl.Enabled = IsFinal == false;
                onBinding = false;
            }
        }


        private void BindConcept(ConceptSchemeType cst, string conceptId)
        {
            c = null;
            if (cst != null)
                c = cst.ConceptList.LocateItem(conceptId) as ConceptType;

            string listConceptId = c == null ? string.Empty : c.Name.ToString();
            if (c != null)
            {
                ConceptList cSorted = new ConceptList();
                foreach (ConceptType co in cst.ConceptList)
                    cSorted.Add(co);
                cSorted.Sort(delegate(ISdmxHierarchyListItem p1, ISdmxHierarchyListItem p2)
                { return p1.Id.CompareTo(p2.Id); });

                multiColumnConceptRef.DataSource = cSorted.GetTableRepresentation(); ;
                // After source was nulled, the displayMember is cleared, so redefine it
                multiColumnConceptRef.DisplayMember = "Code";
                multiColumnConceptRef.ColumnWidths = multiColumnConceptRef.Width.ToString() + ";" + textBoxAgency.Width.ToString() + ";115";
                multiColumnConceptRef.Text = c.Id;
                richTextBoxInfo.Text = c.ContextInfo;
            }
            else
            {
                multiColumnConceptRef.Text = conceptId;
                multiColumnConceptRef.DataSource = null;
                textBoxConceptName.Text = string.Empty;
                richTextBoxInfo.Text = string.Empty;
            }

            buttonErrorConceptRef.Visible = cst == null || c == null;

        }

        // Helper For filling Reference controls
        public static ArtefactList InitSchemeRefControls(ISdmxArtefactRef arSchemeRef,
            MultiColumnComboBox multiCombo, TextBox tbAgency, TextBox tbNameVers)
        {
            ArtefactList alcrlt = ReferenceManager.GetArtefactList(SdmxArtefactType.Concepts);
            ArtefactList alConceptSchemeRefList = new ArtefactList();
            // Sort 
            foreach (Artefact a in alcrlt)
                alConceptSchemeRefList.Add(a);

            alConceptSchemeRefList.Sort(delegate(Artefact p1, Artefact p2)
            { return p1.FullIdent.CompareTo(p2.FullIdent); });


            //   alConceptSchemeRefList.Sort();
            ConceptSchemeType cst = ReferenceManager.LocateConceptScheme(arSchemeRef);

            string conceptSchemeName = cst == null ? string.Empty : cst.Name.ToString();

            multiCombo.DataSource = alConceptSchemeRefList.GetTableRepresentation();
            multiCombo.ColumnWidths = multiCombo.Width.ToString() + ";" + (tbNameVers.Width + 20).ToString() + ":" + tbAgency.Width.ToString();
            if (cst != null)
                multiCombo.Text = cst.Id;
            else
                multiCombo.Text = arSchemeRef.Id;

            if (string.IsNullOrEmpty(arSchemeRef.Id))
            {
                tbNameVers.Text = string.Empty;
                tbAgency.Text = string.Empty;
                multiCombo.Text = null;
            }
            else
            {
                tbNameVers.Text = arSchemeRef.Version + " - " + conceptSchemeName;
                tbAgency.Text = arSchemeRef.AgencyId;
            }

            return alConceptSchemeRefList;
        }
        #endregion

        #region Combo Ref list Event

        private void textBoxConceptSchemeRefName_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (onBinding)
                return;

            DataTable dt = multiColumnConceptSchemeRef.DataSource as DataTable;
            if (dt != null && multiColumnConceptSchemeRef.SelectedIndex >= 0)
            {

                cst = alConceptSchemeRefList[multiColumnConceptSchemeRef.SelectedIndex] as ConceptSchemeType;
                textBoxConceptSchemeRefName.Text = cst.Version + " - " + cst.Name.ToString();
                textBoxAgency.Text = cst.AgencyId;
                arSchemeRef.Id = cst.Id;
                arSchemeRef.Version = cst.Version;
                arSchemeRef.AgencyId = cst.AgencyId;
                arConceptRef.Id = cst.ConceptList.Count > 0 ? cst.ConceptList[0].Id : string.Empty;
                BindConcept(cst, arConceptRef.Id);
            }
            else
            {
                textBoxConceptSchemeRefName.Text = string.Empty;
                textBoxAgency.Text = string.Empty;
            }

        }

        private void multiColumnConceptRef_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (onBinding)
                return;
            
            DataTable dt = multiColumnConceptRef.DataSource as DataTable;
            
            if (dt != null && multiColumnConceptRef.SelectedIndex >= 0)
            {
                arConceptRef.Id = dt.Rows[multiColumnConceptRef.SelectedIndex][0].ToString();
                RaiseConceptSelect();
            }
        }
        #endregion

        #region Navigation

        private void buttonNavigateConcept_Click(object sender, EventArgs e)
        {

            if (arSchemeRef != null && arConceptRef != null)
            {
                try
                {
                    ConceptType cRef = new ConceptType();
                    cRef.Id = arConceptRef.Id;
                    string urn = UrnManager.FullIdToUrn(SdmxArtefactType.Concepts.ToString(),
                       arSchemeRef.FullIdent, cRef, null);
                    UrnParser p = new UrnParser(urn);

                    // If already in memory, navigate otherwhile get from regidtry
                    if (NavigationManager.LocatenavigateProject(SdmxArtefactType.Concepts, arSchemeRef.FullIdent, p) == null)
                        NavigationManager.NavigateWithRegistry(SdmxArtefactType.Concepts, arSchemeRef.FullIdent, true, p);
                }
                catch { }
            }
        }

        private void buttonNavigate_Click(object sender, EventArgs e)
        {
            if (arSchemeRef != null)
            {
                try
                {
                    ArtefactRefTyped art = new ArtefactRefTyped(SdmxArtefactType.Concepts, arSchemeRef.FullIdent);

                    // If already in memory, navigate otherwhile get from registry
                    if (NavigationManager.LocatenavigateProject(art.Type, art.FullIdent, null) == null)
                        NavigationManager.NavigateWithRegistry(art.Type, art.FullIdent, true, null);
                }
                catch { }
            }
        }
        #endregion

        #region Information link click event

        private void richTextBoxInfo_LinkClicked(object sender, LinkClickedEventArgs e)
        {
            try
            {
                System.Diagnostics.Process.Start(e.LinkText);
            }
            catch { }

        }
        #endregion

        #region Urn Paste

        private void buttonAddUrl_Click(object sender, EventArgs e)
        {
            try
            {
                ArtefactRefTyped art = ReferenceManager.ArTypedCopyInstance as ArtefactRefTyped;
                if (art != null)
                {
                    UrnParser p = new UrnParser(ReferenceManager.ArTypedCopyInstanceUrn);
                    if (arSchemeRef != null && arConceptRef != null && p.ArType == SdmxArtefactType.Concepts)
                    {
                        arSchemeRef.Id = p.ArtefactId;
                        arSchemeRef.AgencyId = p.AgencyId;
                        arSchemeRef.Version = p.Version;
                        arConceptRef.Id = p.SubTypeId;
                        BindRef(arSchemeRef, arConceptRef);
                        RaiseConceptSelect();
                    }
                }
            }
            catch { }
        }
        #endregion


    }
}
